<script setup lang="ts">
import { nextTick, reactive, ref } from "vue";
import {
  ITableData,
  IFormState,
  FormStateKeys,
  ITreeSelectData,
  IStateAdd,
  TTreeDataByRole,
} from "./types.ts";
import FormItem from "@/components/autoForm/FormItem.ts";
import { addOptions, formState, initFormData } from "./data.ts";
import { addRow, fetchTabelData } from "@/api/common";
import { NOT_FOUNT_STATUS } from "@/utils/const.ts";
import { ITableResPage } from "@/utils/types/table.ts";
import { roleMenuTreeselect } from "@/api/system/menu.ts";

const emit = defineEmits(["refresh"]);
const modalRef = ref();
const formRef = ref();
const confirmLoading = ref(false);
const types = ref<string>("add");
const state = reactive<IStateAdd>({
  menuTreeData: [],
  plainOptions: [
    { label: "展开/折叠", value: "open" },
    { label: "全选/全不选", value: "checkall" },
  ],
  checkType: [""],
  expandedKeys: [],
});
const getMenuTteee = async () => {
  const { data }: ITableResPage<ITreeSelectData> = await fetchTabelData<
    unknown,
    ITreeSelectData
  >({}, "/system/menu/treeselect");
  state.menuTreeData = data || [];
};
const getMenuTreeByRole = async (roleId: number) => {
  const { menus, checkedKeys }: TTreeDataByRole =
    await roleMenuTreeselect(roleId);
  state.menuTreeData = menus;
  formState.menuIds = checkedKeys;
};
const openAddModal = (type: string, row: ITableData | null) => {
  modalRef.value.openModal();
  types.value = type;
  state.checkType = [""];
  nextTick(() => {
    formRef.value.resetFields();
    if (type === "add") {
      Object.keys(formState).forEach(key => {
        formState[key as FormStateKeys] = initFormData[
          key as FormStateKeys
        ] as never;
      });
      getMenuTteee();
    } else {
      // update
      Object.assign(formState, row);
      formState.changeMenu = false;
      if (row?.roleId) {
        getMenuTreeByRole(row.roleId);
      }
    }
  });
};
defineExpose({ openAddModal });

const checkTypeChange = (checks: string) => {
  if (checks.indexOf("open") !== NOT_FOUNT_STATUS) {
    state.expandedKeys = state.menuTreeData.map(item => item.id) || [];
  } else {
    state.expandedKeys = [];
  }
  if (checks.indexOf("checkall") !== NOT_FOUNT_STATUS) {
    const keys: number[] = [];
    const kkk = (data: ITreeSelectData[]) => {
      data.forEach(item => {
        if (item.children && item.children.length > 0) {
          keys.push(item.id);
          kkk(item.children);
        } else {
          keys.push(item.id);
        }
      });
    };
    kkk(state.menuTreeData);
    formState.menuIds = keys;
  } else {
    formState.menuIds = [];
  }
  formState.changeMenu = true;
};

const menuTreeSelect = (checkedKeys: number[]) => {
  formState.menuIds = checkedKeys;
  formState.changeMenu = true;
};

const modalCancalHandle = () => {
  modalRef.value.closeModal();
  confirmLoading.value = false;
};
const modalSubmitHandle = () => {
  confirmLoading.value = true;
  const method = types.value === "add" ? "post" : "put";
  addRow<IFormState>("/system/role", formState, method)
    .then(() => {
      emit("refresh", {});
      modalCancalHandle();
    })
    .catch(() => (confirmLoading.value = false));
};
</script>

<template>
  <JModal
    :title="types === 'add' ? '新增角色' : '修改角色'"
    ref="modalRef"
    :footer="null"
    :width="600"
  >
    <template #default>
      <a-form
        ref="formRef"
        layout="vertical"
        :model="formState"
        name="addForm"
        @finish="modalSubmitHandle"
      >
        <a-row :gutter="30">
          <template v-for="item in addOptions" :key="item">
            <a-col :span="item.span || 12">
              <a-form-item
                :label="item.label"
                :name="item.field"
                :rules="item.rules"
              >
                <div v-if="item.type === 'custom'">
                  <a-card>
                    <template #title>
                      <a-checkbox-group
                        v-model:value="state.checkType"
                        :options="state.plainOptions"
                        @change="checkTypeChange"
                      />
                    </template>
                    <a-tree
                      v-if="state.menuTreeData.length"
                      style="max-height: 200px; overflow: auto"
                      v-model:checkedKeys="formState[item.field]"
                      checkable
                      :tree-data="state.menuTreeData"
                      :fieldNames="{ title: 'label', key: 'id' }"
                      v-model:expandedKeys="state.expandedKeys"
                      :checkStrictly="false"
                      @check="menuTreeSelect"
                    ></a-tree>
                  </a-card>
                </div>
                <FormItem
                  v-model:value="formState[item.field]"
                  :option="item"
                  style="width: 100%"
                ></FormItem>
              </a-form-item>
            </a-col>
          </template>
        </a-row>
        <div
          style="padding-bottom: 20px; display: flex; justify-content: flex-end"
        >
          <a-button @click="modalCancalHandle">取消</a-button>
          <a-button
            type="primary"
            style="margin-left: 10px"
            html-type="submit"
            :loading="confirmLoading"
          >
            确认
          </a-button>
        </div>
      </a-form>
    </template>
  </JModal>
</template>
